﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using KS.DataWrapper.Interface;

namespace KS.DataWrapper.DataWrapper.LINQ
{

    public class Query<T> : IQueryable<T>, IQueryable, IEnumerable<T>, IEnumerable, IOrderedQueryable<T>, IOrderedQueryable
    {
        private readonly QueryProvider provider;
        private readonly Expression expression;

        public Query(QueryProvider provider)
        {
            if (provider == null)
            {
                throw new ArgumentNullException("provider");
            }
            this.provider = provider;
            this.expression = Expression.Constant(this);
        }

        public Query(QueryProvider provider, Expression expression)
        {
            if (provider == null)
            {
                throw new ArgumentNullException("provider");
            }
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }
            if (!typeof(IQueryable<T>).IsAssignableFrom(expression.Type))
            {
                throw new ArgumentOutOfRangeException("expression");
            }
            this.provider = provider;
            this.expression = expression;
        }

        Expression IQueryable.Expression
        {
            get
            {
                return this.expression;
            }
        }

        Type IQueryable.ElementType
        {
            get
            {
                return typeof(T);
            }
        }

        IQueryProvider IQueryable.Provider
        {
            get
            {
                return this.provider;
            }
        }

        public IEnumerator<T> GetEnumerator()
        {

            var result = this.provider.Execute(this.expression);

      

            if (result is long)
            {
                return GetCount((long)result);
            }
            else
            {
                return ((IEnumerable<T>)result).GetEnumerator();
            }

            
        }


        private IEnumerator<T> GetCount(long count)
        {
            //TODO починить
            List<T> list = new List<T>();
            return list.GetEnumerator();
        }

        //public object GetEnumerator()
        //{
        //    var provo = this.provider as WebApiQueryProvider<T>;
        //    return provo.Execute<T>(this.expression);


        //    //var result = (this.provider.Execute(this.expression) as IEnumerable);
        //    //return ((IEnumerable<T>)result).GetEnumerator();
        //}



        /// <summary>
        /// Кол-во элементов
        /// </summary>
        public long Count()
        {
            return this.provider.Count();
        }

        public override string ToString()
        {
            return this.provider.GetQueryText(this.expression);
        }



        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IEnumerable)this.provider.Execute(this.expression)).GetEnumerator();
        }
    }
}